package com.qfedu.aunt.commons.slot.impl;

import com.qfedu.aunt.commons.constance.RedisConstance;
import com.qfedu.aunt.commons.exception.BusinessException;
import com.qfedu.aunt.commons.manager.RedisManager;
import com.qfedu.aunt.commons.result.ResponseCode;
import com.qfedu.aunt.commons.slot.base.BaseSlot;
import com.qfedu.aunt.commons.utils.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author xiaobobo
 * @title: LimitSlot
 * @projectName aunt_commons_2209
 * @description: TODO
 * @date 2022/11/4  15:25
 */
@Component
@Slf4j
public class LimitSlot implements BaseSlot {

    @Autowired
    private RedisManager redisManager;

    @Override
    public void dealReq(HttpServletRequest request) {
        log.info("执行到了:LimitSlot");
        //当前时间
        long currentTimeMillis = System.currentTimeMillis();
        //接下来计算 1分钟之内的时间
        long miniteAgo=currentTimeMillis-1000*60;
        //接下来计算 1小时之前的时间
        long hourAgo=currentTimeMillis-1000*60*60;
        //然后计算一天之前的时间
        long dayAgo=currentTimeMillis-1000*60*60*24;
        //接下来调用sorted Set中的 count函数来看看个数有多少
        long count=redisManager.count(RedisConstance.getLIMIT()+IpUtils.getIpAddress(request),miniteAgo,currentTimeMillis);
        if(count>50){
            //在这里还需要添加黑名单
            redisManager.addString(RedisConstance.getBLACK()+IpUtils.getIpAddress(request),UUID.randomUUID().toString().replace("-",""),1, TimeUnit.DAYS);

            //说明达到了限流的标准
            throw new BusinessException(ResponseCode.LIMIT_MINITE_EXCEPTION.getCode(),
                    ResponseCode.LIMIT_MINITE_EXCEPTION.getMessage());

        }
        long count1=redisManager.count(RedisConstance.getLIMIT()+IpUtils.getIpAddress(request),hourAgo,currentTimeMillis);
        if(count1>300){
            redisManager.addString(RedisConstance.getBLACK()+IpUtils.getIpAddress(request),UUID.randomUUID().toString().replace("-",""),1, TimeUnit.DAYS);
            //说明达到了限流的标准
            //说明达到了限流的标准
            throw new BusinessException(ResponseCode.LIMIT_HOUR_EXCEPTION.getCode(),
                    ResponseCode.LIMIT_HOUR_EXCEPTION.getMessage());

        }
        long count2=redisManager.count(RedisConstance.getLIMIT()+IpUtils.getIpAddress(request),dayAgo,currentTimeMillis);
        if(count2>1500){
            redisManager.addString(RedisConstance.getBLACK()+IpUtils.getIpAddress(request),UUID.randomUUID().toString().replace("-",""),1, TimeUnit.DAYS);
            //说明达到了限流的标准
            throw new BusinessException(ResponseCode.LIMIT_DAY_EXCEPTION.getCode(),
                    ResponseCode.LIMIT_DAY_EXCEPTION.getMessage());
        }
        //执行到这里 说明没有达到限流标准
        //那么就像里面写入数据回去
        //我们再将IP地址记录到 Set集合中去(这里要永奥IP地址不重复的这个特点)
        redisManager.addSet(RedisConstance.getIP(),IpUtils.getIpAddress(request));
        //然后将请求记录到Redis中
        redisManager.addZSet(RedisConstance.getLIMIT()+ IpUtils.getIpAddress(request),System.currentTimeMillis(), UUID.randomUUID().toString().replace("-",""));

    }
}
